#include "MeiAn.h"
#include "netdata.h"
#include "ezxml.h"
#include "devList.h"

rt_mailbox_t msgAck_mb = RT_NULL;
static rt_uint8_t workStatus = 0;
static rt_mailbox_t rf433_mb;
static rt_uint8_t newDevMsgUserData[64] = {0};

rt_err_t send_hear_data(void)
{
	netDataMailDef  *mail;

	mail = rt_calloc(1, sizeof(netDataMailDef));
	RT_ASSERT(mail);
	
	mail->data = rt_calloc(1,10);
	mail->len = 8;

	rt_memcpy(mail->data, "\x55\xaa\x00\x00\x00\x00\x01\x00", mail->len);
	net_msg_mail_send(mail);

	return RT_EOK;
}

//mode = 0 输出两个标记之间的字符串
//mode = 1 输出标记的有效值
rt_err_t xml_tag_value_string(rt_uint8_t *xml,rt_uint8_t *output,const char *stag,const char *etag,rt_uint8_t mode)
{
	rt_uint8_t *start;
	rt_uint8_t *end;
	rt_uint8_t size;
	rt_uint8_t *buf;
	rt_err_t result = RT_ERROR;

	buf = rt_calloc(1, 64);
	RT_ASSERT(buf);
	
	start = (rt_uint8_t *)rt_strstr((const char *)xml,stag);
	end = (rt_uint8_t *)rt_strstr((const char *)xml,etag);
	if((start != RT_NULL) && (end != RT_NULL))
	{
		size = end - start;
		if(size > 0)
		{
			rt_strncpy((char *)buf, (const char *)(start+rt_strlen(stag)),size);
			rt_kprintf("\n%s\n",buf);
			if(mode == 1)//有效值
			{
				start = (rt_uint8_t *)rt_strstr((const char *)buf,"|");
				end = (rt_uint8_t *)rt_strstr((const char *)buf,"</");
				if(start != RT_NULL)
				{
					size = end - start;
					if(size > 0)
					{
						rt_uint8_t *idStr;
					
						idStr = rt_calloc(1, 64);
						RT_ASSERT(idStr);
					
						rt_strncpy((char *)output, (const char *)(start+rt_strlen("1")),size-1);
						
						rt_free(idStr);
						result = RT_EOK;
					}
				}
			}
			else if(mode == 0)//字符串
			{
				end = (rt_uint8_t *)rt_strstr((const char *)buf,"</");
				if(end != RT_NULL)//结束符存在
				{
					size = end - buf;
					if(size > 0)
					{
						rt_strncpy((char *)output, (const char *)(buf),size);
						result = RT_EOK;
					}
				}
				else
				{
					result = RT_ERROR;
				}
			}

		}
		else
		{
			result = RT_ERROR;
		}
	}

	rt_free(buf);
	return result;
}


rt_err_t send_system_status_msg(rt_uint8_t status)
{
	netDataMailDef  *mail;

	mail = rt_calloc(1, sizeof(netDataMailDef));
	RT_ASSERT(mail);

	switch(status)
	{
		case 0://外出布防
		{
			const char *status_str = "!paT5001XMLD0124000000000464000000000464<Root><UpLoad><AlarmInfo><Cid>STR,4|3401</Cid><Time>DTA,19|2010.01.01.00.00.24</Time><AlarmId>STR,14|F37DAE9E06692D</AlarmId><AreaNo>U32,0,65535|1</AreaNo><AreaName>STR,4|Hall</AreaName><UserNo>U32,0,65535|18</UserNo><UserName>STR,3|cms</UserName><LoginType>TYP,CMS|2</LoginType><Longitude>STR,3|0.0</Longitude><Latitude>STR,3|0.0</Latitude><Height>STR,3|0.0</Height><Channel>S32,0,65535|0</Channel><WanIp>STR,15|192.168.137.164</WanIp></AlarmInfo></UpLoad></Root>0464";
			mail->len = rt_strlen(status_str);
			mail->data = rt_calloc(1,mail->len);
			rt_strncpy((char *)mail->data, (const char *)status_str,rt_strlen(status_str));
			workStatus = STA_GOOUT_GUARD;
			break;
		}
		case 1://系统在家布防
		{
			const char *status_str = "!paT5001XMLD0124000000000464000000000464<Root><UpLoad><AlarmInfo><Cid>STR,4|3441</Cid><Time>DTA,19|2010.01.01.00.00.24</Time><AlarmId>STR,14|F37DAE9E06692D</AlarmId><AreaNo>U32,0,65535|1</AreaNo><AreaName>STR,4|Hall</AreaName><UserNo>U32,0,65535|18</UserNo><UserName>STR,3|cms</UserName><LoginType>TYP,CMS|2</LoginType><Longitude>STR,3|0.0</Longitude><Latitude>STR,3|0.0</Latitude><Height>STR,3|0.0</Height><Channel>S32,0,65535|0</Channel><WanIp>STR,15|192.168.137.164</WanIp></AlarmInfo></UpLoad></Root>0464";
			mail->len = rt_strlen(status_str);
			mail->data = rt_calloc(1,mail->len);
			rt_strncpy((char *)mail->data, (const char *)status_str,rt_strlen(status_str));
			workStatus = STA_HONE_GUARD;
			break;
		}
		case 2://系统撤防
		{
			const char *status_str = "!paT5001XMLD0124000000000464000000000464<Root><UpLoad><AlarmInfo><Cid>STR,4|1401</Cid><Time>DTA,19|2010.01.01.00.00.24</Time><AlarmId>STR,14|F37DAE9E06692D</AlarmId><AreaNo>U32,0,65535|1</AreaNo><AreaName>STR,4|Hall</AreaName><UserNo>U32,0,65535|18</UserNo><UserName>STR,3|cms</UserName><LoginType>TYP,CMS|2</LoginType><Longitude>STR,3|0.0</Longitude><Latitude>STR,3|0.0</Latitude><Height>STR,3|0.0</Height><Channel>S32,0,65535|0</Channel><WanIp>STR,15|192.168.137.164</WanIp></AlarmInfo></UpLoad></Root>0464";
			mail->len = rt_strlen(status_str);
			mail->data = rt_calloc(1,mail->len);
			rt_strncpy((char *)mail->data, (const char *)status_str,rt_strlen(status_str));
			workStatus = STA_None_GUARD;
			break;
		}
	}
	net_msg_mail_send(mail);
	
	return RT_EOK;
}

rt_err_t send_system_statusack_msg(void)
{
	netDataMailDef  *mail;

	mail = rt_calloc(1, sizeof(netDataMailDef));
	RT_ASSERT(mail);

	mail->len = 12;
	mail->data = rt_calloc(1,mail->len);
	
	rt_memcpy(mail->data, "\x55\xaa\x04\x00\x00\x00\x00\xa8\x00\x00\x00\x00", mail->len);
	net_msg_mail_send(mail);

	return RT_EOK;
}

rt_err_t is_start_search_dev(rt_uint8_t *xml)
{
	rt_err_t result = RT_ERROR;
	rt_uint8_t *target;
	rt_uint8_t *start,*end;
	rt_uint8_t *buf;

	buf = rt_calloc(1, 512);
	RT_ASSERT(buf);
	
	

	target = (rt_uint8_t*)rt_strstr((const char*)xml,(const char*)"<DevSearch>");
	if(target != RT_NULL)
	{
		start = (rt_uint8_t*)rt_strstr((const char*)xml,"<Status>");
		if(start != RT_NULL)
		{
			end = (rt_uint8_t*)rt_strstr((const char*)start,"</Status>");
			if(end != RT_NULL)
			{	
				rt_uint8_t size;

				size = end - start;
				
				if(size)
				{
					rt_strncpy((char *)buf, (const char *)start, size);
					rt_kprintf("%s\n",buf);
					if(rt_strstr((const char*)buf,"START"))
					{
						result = RT_EOK;
					}
					else
					{
						result = RT_ERROR;
					}
				}
				else
				{
					result = RT_EOK;
				}
			}
			else
			{
				result = RT_ERROR;
			}
		}
		else
		{
			result = RT_ERROR;
		}
	}

	target = (rt_uint8_t*)rt_strstr((const char*)xml,"<UserData>");
	if(target != RT_NULL)
	{
		end = (rt_uint8_t*)rt_strstr((const char*)xml,"</UserData>");
		rt_strncpy((char *)newDevMsgUserData,(const char *)(target+rt_strlen("<UserData>")),end-target-rt_strlen("<UserData>"));
		rt_kprintf("%s\n",newDevMsgUserData);
	}
	

	rt_free(buf);
	return result;
}


rt_err_t is_stop_search_dev(rt_uint8_t *xml)
{
	rt_err_t result = RT_ERROR;
	rt_uint8_t *target;
	rt_uint8_t *start,*end;
	rt_uint8_t *buf;

	buf = rt_calloc(1, 512);
	RT_ASSERT(buf);
	

	target = (rt_uint8_t*)rt_strstr((const char*)xml,"<DevSearch>");
	if(target != RT_NULL)
	{
		start = (rt_uint8_t*)rt_strstr((const char*)xml,"<Status>");
		if(start != RT_NULL)
		{
			end = (rt_uint8_t*)rt_strstr((const char*)start,"</Status>");
			if(end != RT_NULL)
			{ 
				rt_uint8_t size;

				size = end - start;
				
				if(size)
				{
					rt_strncpy((char *)buf, (const char *)start, size);
					rt_kprintf("%s\n",buf);
					if(rt_strstr((const char*)buf,"STOP"))
					{
						result = RT_EOK;
					}
					else
					{
						result = RT_ERROR;
					}
				}
				else
				{
					result = RT_EOK;
				}
			}
			else
			{
				result = RT_ERROR;
			}
		}
		else
		{
			result = RT_ERROR;
		}
	}

	target = (rt_uint8_t *)rt_strstr((const char *)xml,"<UserData>");
	if(target != RT_NULL)
	{
		end = (rt_uint8_t*)rt_strstr((const char*)xml,"</UserData>");
		rt_strncpy((char *)newDevMsgUserData,(const char *)(target+rt_strlen("<UserData>")),end-target-rt_strlen("<UserData>"));
		rt_kprintf("%s\n",newDevMsgUserData);
	}
	

	rt_free(buf);
	return result;
}


rt_err_t is_devlist_get(rt_uint8_t *xml)
{
	rt_err_t result = RT_EOK;
	rt_uint8_t *target;
	rt_uint8_t *end;

	target = (rt_uint8_t*)rt_strstr((const char*)xml,"<DevList><Total/>");
	if(target != RT_NULL)
	{
		result = RT_EOK;
	}
	else
	{
		result = RT_ERROR;
	}

	target = (rt_uint8_t*)rt_strstr((const char*)xml,"<UserData>");
	if(target != RT_NULL)
	{
		end = (rt_uint8_t *)rt_strstr((const char*)xml,"</UserData>");
		rt_strncpy((char *)newDevMsgUserData,(const char *)(target+rt_strlen("<UserData>")),end-target-rt_strlen("<UserData>"));
		rt_kprintf("%s\n",newDevMsgUserData);
	}
	return result;
}


rt_err_t is_addDev_msg(rt_uint8_t *xml,devListDef *dev)
{
	rt_err_t result = RT_ERROR;
	rt_uint8_t *target;
	rt_uint8_t size;
	rt_uint8_t *buf;

	buf = rt_calloc(1, 64);
	RT_ASSERT(buf);

	target =  (rt_uint8_t *)rt_strstr((const char *)xml,"<AddDev>");
	if(target != RT_NULL)
	{
		result = xml_tag_value_string(xml, buf, "<WlId>", "</WlId>",1);
		if(result == RT_EOK)
		{
			rt_kprintf("<WlId> = %s\n",buf);
			dev->id = atoi(buf);

			rt_memset(buf,0,64);
			result = xml_tag_value_string(xml, buf, "<Name>", "</Name>",1);
			if(result == RT_EOK)
			{
				rt_kprintf("<Name> = %s\n",buf);
				rt_strncpy(dev->name,buf,rt_strlen(buf));

				rt_memset(buf,0,64);
				result = xml_tag_value_string(xml, buf, "<DevType>", "</DevType>",1);
				if(result == RT_EOK)
				{
					rt_kprintf("<DevType> = %s\n",buf);
					dev->type = atoi(buf);

					rt_memset(buf,0,64);
					result = xml_tag_value_string(xml, buf, "<AlarmType>", "</AlarmType>",0);
					if(result == RT_EOK)
					{
						rt_kprintf("<AlarmType> = %s\n",buf);
						rt_strncpy(dev->alarmType,buf,rt_strlen(buf));

						rt_memset(buf,0,64);
						result = xml_tag_value_string(xml, buf, "<AlarmTone>", "</AlarmTone>",0);
						if(result == RT_EOK)
						{
							rt_kprintf("<AlarmTone> = %s\n",buf);
							rt_strncpy(dev->alarmTone,buf,rt_strlen(buf));
						}
					}
				}
			}
		}
	}

	rt_free(buf);
	
	return result;
}


rt_err_t is_editDev_msg(rt_uint8_t *xml,devListDef *dev)
{
	rt_err_t result = RT_ERROR;
	rt_uint8_t *buf;
	rt_uint8_t *target;

	buf = rt_calloc(1, 64);

	target =  (rt_uint8_t *)rt_strstr((const char *)xml,"<EditDev>");
	if(target != RT_NULL)
	{
		result = RT_EOK;
		result = xml_tag_value_string(xml, buf, "<DevNo>", "</DevNo>",1);
		if(result == RT_EOK)//获取ID结果
		{
			rt_uint8_t pos;

			pos = atoi(buf)-1;
			rt_kprintf("pos=%d\n",pos);
			result = xml_tag_value_string(xml, buf, "<AlarmType>", "</AlarmType>",0);
			if(result == RT_EOK)
			{
				devListDef *dev;
				rt_kprintf("buf = %s\n",buf);

				dev = rt_calloc(1, sizeof(devListDef));
				RT_ASSERT(dev);
				
				//devlist_get_content();
				//devlist_pos_content();

				rt_free(dev);
			}
		}
	}
	rt_free(buf);

	return result;
}

rt_err_t upload_devlist_msg(void)
{
	/*netDataMailDef *mail;
	rt_uint8_t lnnum;
	rt_uint32_t size;
	
	mail = rt_calloc(1, sizeof(netDataMailDef));
	RT_ASSERT(mail);
	

	mail->sendbuf = rt_calloc(1, 4098);
	mail->recvbuf = rt_calloc(1, 4098);
	mail->Rsize = 1024;

	lnnum = make_devlist_xml_string(mail->recvbuf);
	rt_sprintf(mail->sendbuf,"<Root><Home><DevList>%s<Total>S32,0,4|%d</Total>\
<Offset>S32,0,4|0</Offset><Ln>S32,0,10|%d</Ln><Err>ERR|00</Err></DevList>\
</Home><UserData>%s</UserData></Root>",mail->recvbuf,lnnum,lnnum,newDevMsgUserData);
	mail->Ssize = rt_strlen(mail->sendbuf);
	

	rt_memset(mail->recvbuf,0,4098);
	rt_memcpy(mail->recvbuf,"\x55\xaa\x60\x01\x00\x00\x06\xa1", 8);
	size = rt_strlen(mail->sendbuf);
	mail->recvbuf[2] = size % 256;
	mail->recvbuf[3] = size / 256;
	rt_memcpy(mail->recvbuf+8,mail->sendbuf,rt_strlen(mail->sendbuf));
	rt_memcpy(mail->sendbuf,mail->recvbuf,size+8);
	rt_memset(mail->recvbuf,0,4098);
	mail->Ssize = size+8;
	
	show_buf_string(mail->sendbuf, mail->Ssize);
	gsm_mail_send(mail);
	
	rt_free(mail->sendbuf);
	rt_free(mail->recvbuf);
	rt_free(mail);
*/
	return RT_EOK;
}


static void msg_recv_process(netDataMailDef *mail)
{
	if((mail->data[6] == 0x03) && (mail->data[7] == 0x20))//登录成功
	{
		ackMailDef *mail;

		mail = rt_calloc(1, sizeof(ackMailDef));
		mail->type = MSG_LOGOIN_ACK;
		rt_mb_send(msgAck_mb, (rt_uint32_t)mail);
		rt_kprintf("设备登录成功\n");
		send_hear_data();
		send_hear_data();
		send_hear_data();
	}
 	else if(mail->data[6]  == 0 && mail->data[7] == 0xa8)// 撤布防
 	{
		send_system_statusack_msg();
		if(mail->data[8] == 0x02)//系统撤防
		{
			rt_kprintf("STA_None_GUARD\n");
			send_system_status_msg(STA_None_GUARD);
		}
		else if(mail->data[8] == 0x01)//系统在家布防
		{
			rt_kprintf("STA_HONE_GUARD\n");
			send_system_status_msg(STA_HONE_GUARD);
		}
		else if(mail->data[8] == 0x00)//系统外出布防
		{
			rt_kprintf("STA_GOOUT_GUARD\n");
			send_system_status_msg(STA_GOOUT_GUARD);
		}
		else if(mail->data[8] == 0x03)
		{
			rt_kprintf("清除报警\n");
		}
	}
	else if(mail->data[6] == 0x06)//开始/停止搜索新设备
	{
		devListDef *dev;
		
		dev = rt_calloc(1,sizeof(devListDef));
		RT_ASSERT(dev);
		
		if(is_start_search_dev(&mail->data[8]) == RT_EOK)//开始搜素设备
		{
			workStatus = STA_ADD_DEV;
			rt_kprintf("STA_ADD_DEV\n");
		}
		else if(is_stop_search_dev(&mail->data[8]) == RT_EOK)//停止搜素设备
		{
			workStatus = STA_None_GUARD;
			rt_kprintf("STA_None_GUARD\n");
		}
		else if(is_devlist_get(&mail->data[8]) == RT_EOK)
		{
			//上传设备列表
			rt_kprintf("上传设备列表\n");
			upload_devlist_msg();
		}
		else if(is_addDev_msg(&mail->data[8],dev) == RT_EOK)
		{
			//保存设备列表
			rt_kprintf("新增设备\n");
			add_to_devlist(dev);
			devlist_save();
			show_devlist();
		}
		else if(is_editDev_msg(&mail->data[8],dev) == RT_EOK)
		{
			rt_kprintf("编辑设备\n");
		}
		else
		{
			rt_kprintf("未开发指令\n");
		}
		
		rt_free(dev);
	}
}

void meian_msg_recv_process(void)
{
	rt_err_t result;
	
	netDataMailDef *mail;
	result = net_msg_mail_recv(&mail);
	if(result == RT_EOK)
	{
		rt_kprintf("mail->data=%s  mail->len=%d\n",mail->data,mail->len);
		if(mail->data != RT_NULL)
		{
			if(mail->len != 0)
			{
				show_hex_string(mail->data,mail->len);
				msg_recv_process(mail);
			}
			rt_free(mail->data);
			rt_free(mail);
		}
	}
}


rt_err_t login_register_server(rt_uint8_t *account,rt_uint8_t *password)
{
	rt_uint8_t *reqMsg;
	netDataMailDef *mail;
	ackMailDef *ack;
	rt_err_t result;

	mail = rt_calloc(1, sizeof(netDataMailDef));
	RT_ASSERT(mail);

	mail->len = 92;
	mail->data = rt_calloc(1, mail->len+8);
	
	rt_memcpy(mail->data,"\x55\xaa\x54\x00\x00\x00\x03 ",8);
	rt_memcpy(mail->data+8,account,8);
	rt_memcpy(mail->data+8+8,"\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x81",12);
	rt_memcpy(mail->data+8+8+12,password,8);
	rt_memcpy(mail->data+8+8+12+8,"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x34\x31\x39\x31\x39-WTXWH\x00\x00\x00\x00\x01\x00\x00\x00\x01\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00MEIA\x00\x00", 56);

	net_msg_mail_send(mail);
  result = rt_mb_recv(msgAck_mb, (rt_uint32_t *)&ack, 300);//等待应答
	if(result == RT_EOK)
	{
		if(ack->type == MSG_LOGOIN_ACK)
		{
			//登录成功
		}
		rt_free(ack);
	}

	return RT_EOK;
}

rt_err_t rf333_msg_mail_send(rf433MeiAnDef *mail)
{
	rt_err_t result;
	
	result = rt_mb_send(rf433_mb, (rt_uint32_t)mail);
	if(result != RT_EOK)//发送失败
	{
		rt_free(mail);
	}

	return result;
}

static void rf433_msg_action_process(rf433MeiAnDef *mail)
{
	
}

static void rf433_msg_recv_process(void)
{
	rf433MeiAnDef *mail;
	rt_err_t result;

	result = rt_mb_recv(rf433_mb, (rt_uint32_t *)&mail, RT_WAITING_NO);
	if(result == RT_EOK)//接收数据成功
	{
		if(mail != RT_NULL)
		{
			show_rf433Hex(mail);
			rf433_msg_action_process(mail);
			rt_free(mail);
		}
	}
	
}


void meian_tx_entry(void *arg)
{
	rt_thread_delay(1500);
	rt_kprintf("%s\n",__FUNCTION__);
	devlist_init();
	show_devlist();
	devinfo_default("118.26.23.97",7779,"gmtss210");
	login_register_server("gmtss210","gmtss210");
	while(1)
	{
		rf433_msg_recv_process();
		rt_thread_delay(1);
	}
}


void meian_rx_entry(void *arg)
{
	rt_thread_delay(1500);
	rt_kprintf("%s\n",__FUNCTION__);
	while(1)
	{
		meian_msg_recv_process();
		rt_thread_delay(1);
	}
}


int meian_thread_init(void)
{
	rt_thread_t thread;

	msgAck_mb = rt_mb_create("msgAck", 5, RT_IPC_FLAG_FIFO);
	RT_ASSERT(msgAck_mb);

	rf433_mb = rt_mb_create("rf433", 10,RT_IPC_FLAG_FIFO);
	RT_ASSERT(msgAck_mb);
	
	thread = rt_thread_create("meian_tx", meian_tx_entry, RT_NULL, 
														512, 21, 10);
	rt_thread_startup(thread);
	
	thread = rt_thread_create("meian_rx", meian_rx_entry, RT_NULL, 
														512, 21, 10);
	rt_thread_startup(thread);

	return 0;
}
INIT_APP_EXPORT(meian_thread_init);


void net_crc16_test(void)
{
		rt_kprintf("%x\n",net_crc16("\x06\x00\x00\x00\x01",5));
}


void msg_send_test()
{	
	netDataMailDef *mail;

	mail = rt_calloc(1, sizeof(netDataMailDef));
	RT_ASSERT(mail);
	mail->data = rt_calloc(1,512);
	mail->len = 6;
	rt_strncpy(mail->data, "123456", 6);

	net_msg_mail_send(mail);
}


void ezxml_test(void)
{
	const char *test = "<Root><Home><DevList><L0><DevNo>S32,0,256|2</DevNo><DevType>TYP,DOOR_SENSOR|10</DevType><Name>STR,16|</Name><AreaNo>S32,0,32|1</AreaNo><AlarmType>TYP,BURRGLAR|3</AlarmType><AlarmTone>TYP,TONE|1</AlarmTone><UploadRd>TYP,ON|1</UploadRd><RfId>STR,9|230001001</RfId><WlId>STR,9|230001001</WlId><CtlType>TYP,RF|0</CtlType><Online>TYP,NO|1</Online><Sn>S32,0,4|1</Sn><S0><DoorStatus>S32,0,2147483647|0</DoorStatus></S0></L0><Total>S32,0,2|1</Total><Offset>S32,0,2|0</Offset><Ln>S32,0,10|1</Ln><Err>ERR|00</Err></DevList></Home><UserData>STR,7|2426560</UserData></Root>";
	ezxml_t xml;

	xml = ezxml_parse_str((char *)test,rt_strlen(test));

}
#ifdef RT_USING_FINSH
#include <finsh.h>
/* 输出udpserv函数到finsh shell中 */
FINSH_FUNCTION_EXPORT(net_crc16_test, startup udp client);
FINSH_FUNCTION_EXPORT(msg_send_test, startup udp client);
FINSH_FUNCTION_EXPORT(ezxml_test, startup udp client);

#endif



